最後的五天我們要執行Final Mission — 5 日實作計畫,設計一個Galactic Explorer!
把前面 25 天學的所有技能都串起來了~!
而今日目標:建立整體網站結構與風格基底。
A.網站主題名稱與頁面結構
/
:主頁(星際入口、導航)/planets
:星球知識頁/diary
:宇宙觀察日誌/scanner
:生物探測器小遊戲<router-link>
導頁。B.設計風格
在有 package.json
的專案根目錄執行:
*需要 Vue Router、Element Plus*
npm i vue-router@4 element-plus
*(可選)安裝圖示*
npm i @iconify/vue
a. 建立目錄
src/
├─ router/
│ └─ index.js
├─ views/
│ ├─ Home.vue
│ ├─ Planets.vue
│ ├─ Diary.vue
│ ├─ Scanner.vue
│ └─ NotFound.vue
├─ components/
│ └─ NavBar.vue
└─ styles/
└─ theme.css
b. src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import Planets from '../views/Planets.vue'
import Diary from '../views/Diary.vue'
import Scanner from '../views/Scanner.vue'
import NotFound from '../views/NotFound.vue'
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/', name: 'home', component: Home },
{ path: '/planets', name: 'planets', component: Planets },
{ path: '/diary', name: 'diary', component: Diary },
{ path: '/scanner', name: 'scanner', component: Scanner },
{ path: '/:pathMatch(.*)*', name: '404', component: NotFound }
],
scrollBehavior: () => ({ top: 0 })
})
export default router
a. src/main.js
import { createApp } from 'vue'
import App from './App.vue'
// Router
import router from './router'
// Element Plus
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
// 全站樣式(星空主題)
import './styles/theme.css'
createApp(App)
.use(router)
.use(ElementPlus)
.mount('#app')
b. index.html
(加入字體)
在 <head>
增加(讓標題更有宇宙感):
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;600;800&display=swap" rel="stylesheet">
a. src/components/NavBar.vue
<template>
<header class="nav">
<div class="brand">🚀 Galactic Explorer</div>
<el-menu mode="horizontal" :ellipsis="false" class="menu" router>
<el-menu-item index="/">首頁</el-menu-item>
<el-menu-item index="/planets">星球知識</el-menu-item>
<el-menu-item index="/diary">觀察日誌</el-menu-item>
<el-menu-item index="/scanner">生物探測器</el-menu-item>
</el-menu>
</header>
</template>
<script setup>
/* Element Plus 的 <el-menu router> 會自動根據路由高亮 */
</script>
<style scoped>
.nav {
position: sticky; top: 0; z-index: 50;
display: flex; align-items: center; justify-content: space-between;
padding: 10px 16px; backdrop-filter: blur(8px);
background: linear-gradient(180deg, rgba(11,16,32,.85), rgba(11,16,32,.55));
border-bottom: 1px solid rgba(167,139,250,.2);
}
.brand {
font-family: 'Orbitron', system-ui, sans-serif;
font-weight: 800; letter-spacing: .5px;
color: #e0e7ff;
}
.menu { background: transparent; border-bottom: none; }
:deep(.el-menu--horizontal>.el-menu-item.is-active) {
color: #a78bfa; border-bottom-color: #a78bfa;
}
</style>
b. src/App.vue
<template>
<div class="sky">
<div class="stars"></div>
<NavBar />
<main class="page">
<router-view />
</main>
<footer class="ft">© Orbit Coders · Galactic Explorer</footer>
</div>
</template>
<script setup>
import NavBar from './components/NavBar.vue'
</script>
<style scoped>
.page { max-width: 1080px; margin: 24px auto; padding: 0 16px; }
.ft { text-align:center; color:#94a3b8; padding: 24px 0 40px; }
</style>
src/styles/theme.css
:root{
--bg-deep:#0b1020; /* 深藍底 */
--text-main:#e0e7ff; /* 銀白字 */
--text-dim:#94a3b8;
--accent:#a78bfa; /* 螢光紫 */
--card:#0f172a;
color-scheme: dark;
}
html,body,#app{ height:100%; }
body{ margin:0; background: var(--bg-deep); color: var(--text-main); font: 16px/1.6 ui-sans-serif, system-ui; }
.sky { position: relative; min-height:100vh; }
.stars{
position: fixed; inset: 0; pointer-events: none;
background:
radial-gradient(2px 2px at 20% 30%, #fff6 40%, transparent 41%) repeat,
radial-gradient(1px 1px at 70% 60%, #fff4 40%, transparent 41%) repeat;
background-size: 600px 600px, 800px 800px;
animation: drift 120s linear infinite;
opacity: .6;
}
@keyframes drift {
from { transform: translate3d(0,0,0); }
to { transform: translate3d(-2000px, 800px, 0); }
}
/* 常用卡片 */
.card {
background: var(--card);
border: 1px solid rgba(167,139,250,.2);
border-radius: 16px;
padding: 16px;
}
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
1.src/views/Home.vue
<template>
<section class="hero card">
<h1>🪐 Galactic Explorer</h1>
<p>探索星球知識、撰寫觀察日誌,啟動生物探測器小遊戲。</p>
<el-space wrap>
<el-button type="primary" @click="$router.push('/planets')">開始探索星球</el-button>
<el-button @click="$router.push('/diary')">打開觀察日誌</el-button>
<el-button type="success" @click="$router.push('/scanner')">啟動探測器</el-button>
</el-space>
</section>
</template>
<script setup></script>
<style scoped>
.hero h1{ font-family: 'Orbitron', system-ui; font-size: 32px; margin: 0 0 8px; }
.hero p{ color: var(--text-dim); margin: 0 0 12px; }
</style>
2.src/views/Planets.vue
<template>
<section class="card">
<h2>🗺️ 星球知識庫</h2>
<p class="dim">明天會接上 v-for 清單與動態路由到詳細頁。</p>
<el-alert title="提示" type="info" :closable="false" show-icon>
範例資料將放在 <code>src/data/planets.json</code>
</el-alert>
</section>
</template>
<script setup></script>
<style scoped>.dim{ color:var(--text-dim); }</style>
3.src/views/Diary.vue
<template>
<section class="card">
<h2>📓 宇宙觀察日誌</h2>
<p class="dim">後天會串 localStorage,讓日誌重整後依然保存。</p>
<el-input
v-model="draft"
type="textarea"
:rows="5"
placeholder="今天看見了……"
class="mb"
/>
<el-button type="primary" @click="save">暫存(僅示意)</el-button>
</section>
</template>
<script setup>
import { ref } from 'vue'
const draft = ref('')
function save(){ /* Day 28 會補完整 */ }
</script>
<style scoped>
.mb{ margin: 12px 0 0; }
.dim{ color:var(--text-dim); }
</style>
4.src/views/Scanner.vue
<template>
<section class="card">
<h2>🛰️ 生物探測器</h2>
<p class="dim">後續將加入燃料值、隨機生物、動畫與收藏機制。</p>
<el-button type="success">探索(預留)</el-button>
</section>
</template>
<script setup></script>
<style scoped>.dim{ color:var(--text-dim); }</style>
5.src/views/NotFound.vue
<template>
<section class="card">
<h2>404:迷失在宇宙中</h2>
<el-button type="primary" @click="$router.push('/')">回到地球</el-button>
</section>
</template>
<script setup></script>
最後執行看看網站會長上面的樣子!你也可以隨自己喜歡去更改設計美編~我們明天會加上展示宇宙星球資訊,能點選切換細節頁面。
參考資源
https://vuejs.org/guide
https://www.runoob.com/vue3